package myJs.cps

import myJs.Implicits._
import myJs.api.Api
import myJs.myPkg.{AjaxOptions, Params, Select2Options}
import myJs.myPkg.jquery.{$, JQuery}
import org.scalajs.dom
import org.scalajs.dom.{Event, html}
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.core.facade.React
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.Dynamic.{global => g}

/**
 * Created by yz on 21/1/2022
 */
@react object PureAsyncSelect2Cp {

  case class Props(name: String = "", hasBv: Boolean = false, formJq: JQuery = $("#form"),
                   value: js.UndefOr[String] = js.undefined, onChange: js.UndefOr[String => Unit] = js.undefined,
                   width: String = "150px", allowClear: Boolean = false, url: String)

  val component = FunctionalComponent[Props] { props =>

    val (myV, setMyV) = useState("")

    val selectRef = React.createRef[html.Select]
    val placeholder = "Search for a repository"

    object FTool {

      def refreshSelect2 = {
        val y = selectRef.current
        val jq = $(y)
        val dataF = (params: Params) => {
          val page = params.page.getOrElse(1)
          val pageSize = params.pageSize.getOrElse(30)
          js.Dictionary(
            "q" -> params.term,
            "page" -> page,
            "pageSize" -> pageSize,
          ): JDJAn
        }

        val resultsF = (data: JDJAn) => {
          data
        }
        val options = Select2Options(ajax =
          AjaxOptions(url = props.url, dataType = "json", delay = 250, data = dataF, processResults = resultsF, cache = true),
          minimumInputLength = 2, placeholder = placeholder)
        jq.mySelect2(options)
      }

    }

    useEffect(() => {
      val y = selectRef.current
      val jq = $(y)
      FTool.refreshSelect2
      jq.select2Val(getValue)
      jq.on("change", (e: Event) => {
        val v = $(y).select2ValSingle
        onChange(v)
      })
      if (props.hasBv) {
        val bv = props.formJq.bv
        val curJq = $(y)
        bv.addField(curJq)
      }
      () => {
        val y = selectRef.current
        if (props.hasBv) {
          val bv = props.formJq.bv
          val curJq = $(y)
          bv.updateStatus(curJq, "VALID").removeField(curJq)
        }
      }
    }, List()
    )

    useEffect(() => {
      val y = selectRef.current
      val jq = $(y)
      val v = getValue
      jq.empty().append(s"<option value='${v}' selected='selected'>${v}</option>")
      jq.select2Val(v)
    }, List(props.value)
    )

    useEffect(() => {
      FTool.refreshSelect2
    }, List(props.url)
    )

    def getValue = {
      props.value.map(v => v).getOrElse(myV)
    }

    def onChange(v: String) = {
      props.onChange.toOption match {
        case Some(f) => f(v)
        case None => setMyV(v)
      }
    }

    select(className := "form-control", name := s"${props.name}",
      style := Style(
        width = s"${props.width}"
      ), ref := selectRef,
    )

  }

}
